package chai.ningning.tcp;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Set;

public class SecondServer {

    // 被逼无奈不得不用static修饰的成员变量
    private static final Set<Socket> CLIENTS = new HashSet<>();

    private static final Charset DEFAULT_CHARSET = Charset.forName( "UTF-8" );

    static class ServiceThread extends Thread {

        private Socket client ;

        public ServiceThread(Socket client) {
            this.client = client;
        }

        @Override
        public void run() {
            try {
                // 通过client对象获取该Socket所表示的客户端的IP地址和端口
                InetSocketAddress isa = (InetSocketAddress) client.getRemoteSocketAddress();
                String addr = isa.getHostString() + ":" + isa.getPort();
                // 读取客户端发送过来的数据
                InputStream in = client.getInputStream(); // 用来读取客户端数据的字节输入流
                Reader reader = new InputStreamReader(in, DEFAULT_CHARSET); // 字符输入流
                BufferedReader br = new BufferedReader(reader); // 根据字符输入流创建缓冲流(仍然是字符流)
                String message;
                while ((message = br.readLine()) != null) {
                    message = addr + " 说: " + message ;
                    System.out.println(message);
                    // 将接收到的数据群发给所有客户端
                    for (Socket s : CLIENTS) {
                        OutputStream out = s.getOutputStream(); // 可以向s所对应客户端输出数据的字节输出流
                        PrintStream pw = new PrintStream(out); // 创建一个字节打印流
                        pw.println( message );
                    }
                }
            } catch ( IOException e ) {
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) throws IOException {

        final String host = "1.0.0.58" ; // 指定主机地址
        final int port = 55555 ; // 指定端口号

        System.out.println( "创建ServerSocket对象" );
        ServerSocket server = new ServerSocket();

        System.out.println( "初始化服务器..." );
        SocketAddress endpoint = new InetSocketAddress( host , port );
        server.bind( endpoint );

        while(true){
            System.out.println( "正在监听来自客户端的连接" );
            Socket client = server.accept();
            System.out.println( "监听到: " + client );
            // 将监听到的客户端添加到Set集合中
            CLIENTS.add( client );
            // 创建一个为当前监听到的客户端服务的线程
            Thread t = new ServiceThread( client );
            // 启动线程
            t.start();
        }

    }

}
